#pragma once

#include "Point.h"

template <typename T>
class BasicRect 
{
public:
	T x;
	T y;
	T w;
	T h;

	BasicRect(T x = 0, T y = 0, T w = 0, T h = 0) : x(x), y(y), w(w), h(h) 
	{
	}

	T right() const;
	T bottom() const;

	bool operator==(const BasicRect<T>& rect ) const;
	bool contains( const BasicPoint<T>& point ) const;

	bool intersects( const BasicRect<T>& rect ) const;
	bool intersectInplace( const BasicRect<T>& rect );
};


template<typename T>
std::ostream& operator<<(std::ostream& os, const BasicRect<T>& r) 
{
	return
		os << "("<<r.x<<","<<r.y<<")-("<<r.w<<","<<r.h<<")";
}

//////////////// INLINE FUNCTIONS /////////////////////////

template<typename T>
inline T BasicRect<T>::right() const 
{
	return x + w;
}

template<typename T>
inline T BasicRect<T>::bottom() const 
{
	return y + h;
}

template<typename T>
inline bool BasicRect<T>::operator==(const BasicRect<T>& rect ) const 
{
	return
		x == rect.x && y == rect.y && w == rect.w && h == rect.h;
}

template<typename T>
inline bool BasicRect<T>::contains( const BasicPoint<T>& point ) const 
{
	return
		(((point.x >= x) && (point.x <= x + w))
			&& ((point.y >= y) && (point.y <= y + h)));
}


template<typename T>
inline bool BasicRect<T>::intersectInplace( const BasicRect<T>& rectangle ) 
{
	x = x - rectangle.x;
	y = y - rectangle.y;


	if (x < 0) 
	{
		w += x;
		x = 0;
	}

	if (y < 0) 
	{
		h += y;
		y = 0;
	}

	if (x + w > rectangle.w) 
	{
		w = rectangle.w - x;
	}

	if (y + h > rectangle.h) 
	{
		h = rectangle.h - y;
	}

	x += rectangle.x;
	y += rectangle.y;

	if (w <= 0 || h <= 0) 
	{
		h = 0;
		w = 0;
		return false;
	}
	return true;
}

template<typename T>
inline bool BasicRect<T>::intersects( const BasicRect<T>& rectangle ) const 
{
	T _x = x - rectangle.x;
	T _y = y - rectangle.y;
	T _w = w;
	T _h = h;


	if (_x < 0) 
	{
		_w += _x;
		_x = 0;
	}

	if (_y < 0) 
	{
		_h += _y;
		_y = 0;
	}

	if (_x + _w > rectangle.w) 
	{
		_w = rectangle.w - _x;
	}

	if (_y + _h > rectangle.h) 
	{
		_h = rectangle.h - _y;
	}

	if (_w <= 0 || _h <= 0) 
	{
		return false;
	}
	return true;
}

typedef BasicRect<int> Rect;
typedef BasicRect<float> FloatRect;
typedef BasicRect<double> DoubleRect;
